package com.leyou.page.service.impl;

import com.leyou.common.exceptions.LyException;
import com.leyou.common.utils.JsonUtils;
import com.leyou.item.client.ItemClient;
import com.leyou.item.dto.*;
import com.leyou.page.service.GoodsPageService;
import com.leyou.page.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 虎哥
 */
@Service
public class GoodsPageServiceImpl implements GoodsPageService {


    @Autowired
    private ItemClient itemClient;
    @Autowired
    private StringRedisTemplate redisTemplate;

    private final static String SPU_KEY_PREFIX = "page:spu:id:";
    private final static String DETAIL_KEY_PREFIX = "page:detail:id:";
    private static final String SKU_KEY_PREFIX = "page:sku:id:";
    private static final String CATEGORY_KEY_PREFIX = "page:category:id:";
    private static final String BRAND_KEY_PREFIX = "page:brand:id:";
    private static final String SPEC_KEY_PREFIX = "page:spec:id:";

    @Override
    public String loadSpuData(Long spuId) {
        // 1.查询DTO
        SpuDTO spuDTO = itemClient.querySpuById(spuId);
        if(!spuDTO.getSaleable()){
            // 商品已经下架
            throw new LyException(404, "商品已经下架！");
        }
        // 2.转为VO
        SpuVO spuVO = spuDTO.toEntity(SpuVO.class);
        spuVO.setCategoryIds(spuDTO.getCategoryIds());
        // 3.序列化为JSON   序列化：对象-->JSON  反序列化：JSON --> 对象
        String json = JsonUtils.toJson(spuVO);
        // 4.写入redis
        redisTemplate.opsForValue().set(SPU_KEY_PREFIX + spuId, json);
        // 5.返回
        return json;
    }

    @Override
    public String loadSpuDetailData(Long spuId) {
        // 1.查询DTO
        SpuDetailDTO detailDTO = itemClient.querySpuDetailById(spuId);
        // 3.序列化为JSON
        String json = JsonUtils.toJson(detailDTO);
        // 4.写入redis
        redisTemplate.opsForValue().set(DETAIL_KEY_PREFIX + spuId, json);
        // 5.返回
        return json;
    }

    @Override
    public String loadSkuListData(Long spuId) {
        // 1.查询DTO
        List<SkuDTO> skuList = itemClient.querySkuBySpuId(spuId);
        // 3.序列化为JSON
        String json = JsonUtils.toJson(skuList);
        // 4.写入redis
        redisTemplate.opsForValue().set(SKU_KEY_PREFIX + spuId, json);
        // 5.返回
        return json;
    }

    @Override
    public String loadCategoriesData(List<Long> ids) {
        // 1.查询DTO
        List<CategoryDTO> dtoList = itemClient.queryCategoryByIds(ids);
        // 2.转为VO
        List<CategoryVO> list = dtoList.stream()
                .map(dto -> dto.toEntity(CategoryVO.class)).collect(Collectors.toList());
        // 3.序列化为JSON
        String json = JsonUtils.toJson(list);
        // 4.写入redis
        redisTemplate.opsForValue().set(CATEGORY_KEY_PREFIX + ids.get(ids.size() - 1), json);
        // 5.返回
        return json;
    }

    @Override
    public String loadBrandData(Long brandId) {
        // 1.查询DTO
        BrandDTO brandDTO = itemClient.queryBrandById(brandId);
        // 2.转为VO
        BrandVO brandVO = brandDTO.toEntity(BrandVO.class);
        // 3.序列化为JSON
        String json = JsonUtils.toJson(brandVO);
        // 4.写入redis
        redisTemplate.opsForValue().set(BRAND_KEY_PREFIX + brandId, json);
        // 5.返回
        return json;
    }

    @Override
    public String loadSpecData(Long categoryId) {
        // 1.查询DTO
        List<SpecGroupDTO> groupDTOList = itemClient.querySpecList(categoryId);
        // 2.转为VO
        List<SpecGroupVO> groupVOList = new ArrayList<>(groupDTOList.size());
        for (SpecGroupDTO groupDTO : groupDTOList) {
            // 把GroupDTO转为GroupVO
            SpecGroupVO groupVO = new SpecGroupVO();
            // 填name
            groupVO.setName(groupDTO.getName());
            // 取出paramDTO
            List<SpecParamDTO> params = groupDTO.getParams();
            // paramDTO转为ParamVO
            List<SpecParamVO> paramVOList = params.stream()
                    .map(paramDTO -> paramDTO.toEntity(SpecParamVO.class)).collect(Collectors.toList());
            // 填paramVOList
            groupVO.setParams(paramVOList);
            groupVOList.add(groupVO);
        }
        // 3.序列化为JSON
        String json = JsonUtils.toJson(groupVOList);
        // 4.写入redis
        redisTemplate.opsForValue().set(SPEC_KEY_PREFIX + categoryId, json);
        // 5.返回
        return json;
    }

    @Override
    public void saveBrandVO(BrandVO brandVO) {
        // 3.序列化为JSON
        String json = JsonUtils.toJson(brandVO);
        // 4.写入redis
        redisTemplate.opsForValue().set(BRAND_KEY_PREFIX + brandVO.getId(), json);
    }

    @Override
    public void deleteBrandById(Long id) {
        redisTemplate.delete(BRAND_KEY_PREFIX + id);
    }

    @Override
    public void deleteSkuList(Long spuId) {
        redisTemplate.delete(SKU_KEY_PREFIX + spuId);
    }
}
